/*
 * @(#)SendSmsAction.java $version 2011. 10. 14
 * 
 * Copyright 2011 NHN Corp. All rights Reserved.
 * NHN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.hangame.mbl.action;

import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hangame.mbl.bo.CommonBO;
import com.hangame.mbl.bo.SmsBO;
import com.hangame.mbl.bo.game.GameBO;
import com.hangame.mbl.bo.http.CommonHttpBO;
import com.hangame.mbl.constant.CommonConst;
import com.hangame.mbl.model.Game;
import com.hangame.mbl.util.CommonUtil;

import com.nhncorp.lucy.common.data.DataHandlerFactory;
import com.nhncorp.lucy.security.permission.Permissions;
import com.nhncorp.lucy.web.context.WebContext;
import com.nhncorp.lucy.web.metadata.Inject;
import com.nhncorp.lucy.web.metadata.Properties;

// TODO: Auto-generated Javadoc
/**
 * The Class SendSmsAction.
 * 
 * @author khpark
 */
public class SendSmsAction extends SmartPortalAction {
	
	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -4553112773467744189L;
	
	/** The Constant URL_HG_MOBILE. */
	private static final String URL_HG_MOBILE = DataHandlerFactory.getDataHandler().get("url/mbl_short_url"); //한게임모바일site URL
	
	/** The Constant URL_SMART_MOBILE. */
	private static final String URL_SMART_MOBILE = DataHandlerFactory.getDataHandler().get("url/mobile_smart"); // 스마트폰 한게임 모바일 URL

	/** The log. */
	private static Log log = LogFactory.getLog(SendSmsAction.class);

	/** The sms bo. */
	private SmsBO smsBO;
	
	/** The common bo. */
	private CommonBO commonBO;
	
	/** The game bo. */
	private GameBO gameBO;
	
	/** The common http bo. */
	private CommonHttpBO commonHttpBO;

	/**
	 * Sets the sms bo.
	 * 
	 * @param smsBO the new sms bo
	 */
	@Inject(beanId = "smsBO")
	public void setSmsBO(SmsBO smsBO) {
		this.smsBO = smsBO;
	}

	/**
	 * Sets the common bo.
	 * 
	 * @param commonBO the new common bo
	 */
	@Inject(beanId = "commonBO")
	public void setCommonBO(CommonBO commonBO) {
		this.commonBO = commonBO;
	}

	/**
	 * Sets the game bo.
	 * 
	 * @param gameBO the new game bo
	 */
	@Inject(beanId = "gameBO")
	public void setGameBO(GameBO gameBO) {
		this.gameBO = gameBO;
	}

	/**
	 * Sets the common http bo.
	 * 
	 * @param commonHttpBO the new common http bo
	 */
	@Inject(beanId = "commonHttpBO")
	public void setCommonHttpBO(CommonHttpBO commonHttpBO) {
		this.commonHttpBO = commonHttpBO;
	}

	/**
	 * SMS 보내기 팝업 띄우기.
	 * 
	 * @return the string
	 * @return
	 */
	//@Properties(values = {"popup=true"})
	@Permissions(required = "login")
	public String popupSendSms() {

		String smsMsg = "";

		boolean isForSmsForHGMobile = "smsForHGMobile".equals(params.getString("reqType")); //한게임모바일URL보내려는 경우인지
		boolean isForSmsForSmartMobile = "smsForSmartMobile".equals(params.getString("reqType")); // 스마트폰 한게임 모바일 URL 보내려는 경우.
		if (isForSmsForHGMobile) {
			smsMsg = getSmsMsgForHGMobile();
		} else if (isForSmsForSmartMobile) {
			smsMsg = getSmsMsgForSmartMobile();
		} else { //게임관련 SMS 보내려는 경우
			int gameNo = NumberUtils.toInt(params.getString("gameNo"), -1);
			if (gameNo == -1) {
				//TODO alert and close
			}

			smsMsg = getSmsMsg(gameNo);
		}

		setAttribute("smsMsg", smsMsg);

		boolean hasHspPhoneNum = false; //TODO hsp에 전화번호 있는지 여부. hsp에 전화번호가 있으면, hsp전화번호가 한게임에 등록된 전화번호보다 우선된다. 현재 hsp쪽에서 전화번호 가져오는 기능이 없음. 무조건 한게임에 등록된 전화 번호 가져오도록 함.
		setAttribute("hasHspPhoneNum", hasHspPhoneNum);

		String phoneNum = "";
		phoneNum = this.commonHttpBO.getMobilePhoneNumFromMid(getUser().getMemberno()); //한게임 전화번호

		setAttribute("phoneNum", phoneNum);
		setAttribute("phoneNumStripped", StringUtils.replace(phoneNum, "-", ""));

		return "popupSendSms";
	}

	/**
	 * SMS 실제 보내기.
	 * 
	 * @return the string
	 * @return
	 */
	@Properties(values = {"popup=true"})
	@Permissions(required = "login")
	public String sendSms() {
		//String sndNum = StringUtils.defaultIfEmpty(params.getString("sndNum"), "");
		String sndNum = this.commonHttpBO.getMobilePhoneNumFromMid(getUser().getMemberno()); //한게임 전화번호
		sndNum = StringUtils.replace(sndNum, "-", "");
		int gameNo = NumberUtils.toInt(params.getString("gameNo"), -1);
		
		if (StringUtils.isEmpty(sndNum)) {
			return setJsonMsgResult(WebContext.getMessage("sms.make.sure.your.phone.num"));
		}

		String userId = getUser().getUserId();

		int phoneNumCnt = NumberUtils.toInt(params.getString("phoneNumCnt"), 0); //보낼갯수
		ArrayList<String> failRcvNumList = new ArrayList<String>(); //실패한 수신번호 리스트

		boolean isAllSucc = true; //전체 프로세스 성공 여부
		boolean isAbleToSend = false; //SMS 보낼 수 있는 상태 여부
		boolean isExcessive = false; //보낼 수 있는 SMS 갯수 초과 여부

		int memberCnt = this.commonBO.getMemberCountByIdForSms(userId);

		boolean hasMyRecord = memberCnt > 0;
		if (hasMyRecord) {
			boolean belongToValidDate = this.commonBO.getCountBelongValidDateRangeByIdForSms(userId) > 0;
			if (belongToValidDate) { //보내기가 유효한 날 범위 인 경우
				int sentCount = this.commonBO.getSentSmsCountById(userId); //이미 보낸 갯수
				isExcessive = (sentCount + phoneNumCnt) > CommonConst.MAX_SMS_COUNT_IN_A_WEEK; //보낼 수 있는지 갯수 초과했는지?
				if (isExcessive) { //초과한 경우
					isAllSucc = false;
				} else {
					isAbleToSend = true;
				}
			} else { //보내기 날짜 범위 지난경우. update해야함
				this.commonBO.updateNewSmsPeriod(userId);
				isAbleToSend = true;
			}

			log.info("belongToValidDate : " + belongToValidDate);
		} else { //없는 경우
			//새로운 레코드를 추가 시킨다
			this.commonBO.insertNewSmsUser(userId);
			isAbleToSend = true;
		}

		int succCnt = 0; //전송에 성공한 갯수
		if (isAbleToSend) {
			String contentForSms = "";

			boolean isForSmsForHGMobile = "smsForHGMobile".equals(params.getString("reqType")); //한게임모바일URL보내려는 경우인지
			boolean isForSmsForSmartMobile = "smsForSmartMobile".equals(params.getString("reqType")); // 스마트폰 한게임 모바일 URL 보내려는 경우.
			if (isForSmsForHGMobile) {
				contentForSms = getSmsMsgForHGMobile();
			} else if (isForSmsForSmartMobile) {
				contentForSms = getSmsMsgForSmartMobile();
			} else { //게임관련 SMS 보내려는 경우
				if (gameNo == -1) { //gameNo 안넘어 온 경우.
					return setJsonMsgResult(WebContext.getMessage("sms.result.failure"));
				}

				contentForSms = getSmsMsg(gameNo);
			}

			if (StringUtils.isEmpty(contentForSms)) {
				return setJsonMsgResult(WebContext.getMessage("sms.no.content"));
			}
			
			for (int i = 1; i <= phoneNumCnt; i++) {
				String phoneNum = params.getString("phoneNum" + i);
				if (StringUtils.isNotEmpty(phoneNum)) {
					boolean isSucc = this.smsBO.sendSMSForOne(sndNum, phoneNum, contentForSms);

					if (isSucc) {
						this.commonBO.insertSmsLog(userId, sndNum, phoneNum, gameNo); //로그남김
						succCnt += 1;
					} else { //실패인 경우. 실패한 수신번호 리스트에 추가
						isAllSucc = false;
						failRcvNumList.add(phoneNum);
					}
				}
			}
		}

		String resultMsg = "";
		if (!isAllSucc) { //보내기 실패한경우
			if (isExcessive) { //보낼수있는 갯수 초과한 경우
				resultMsg = WebContext.getMessage("sms.result.count.excess", CommonConst.MAX_SMS_COUNT_IN_A_WEEK);
				return setJsonMsgResult(resultMsg);
			} else { //일반적인 오류로 보내지 못한 경우
				resultMsg = WebContext.getMessage("sms.result.failure");
				return setJsonMsgResult(resultMsg);
			}
		} else { //보내기 성공한 경우
			resultMsg = WebContext.getMessage("sms.result.complete");
			//전송 count 증가시킴
			if (succCnt > 0) {
				this.commonBO.updateSentSmsCount(userId, succCnt);
			}

			return setJsonMsgResult(resultMsg);
		}
	}

	/**
	 * json 결과를 setAttribute해줌.
	 * 
	 * @param resultMsg the result msg
	 * @return the string
	 * @return
	 */
	private String setJsonMsgResult(String resultMsg) {
		String jsonResult = "";
		jsonResult += "{";
		jsonResult += "\"resultMsg\" : \"" + resultMsg + "\"";
		jsonResult += "}";

		setAttribute("JSON_RESULT", jsonResult);

		return "commonJsonResult";
	}

	/**
	 * gameNo에 해당하는 sms 문구 가져오기.
	 * 
	 * @param gameNo the game no
	 * @return the sms msg
	 */
	private String getSmsMsg(int gameNo) {
		String smsMsg = "";

		Game game = this.gameBO.getGameDetailInfo(gameNo);

		String gameName = game.getGameName();
		String simpleDesc = game.getSimpleDescription();
		String url = game.getRedirectUrl();

		String tmpSmsMsg1 = simpleDesc + " " + gameName + " " + url;
		String tmpSmsMsg2 = gameName + " " + url;

		if (CommonUtil.isLongerThan80Byte(tmpSmsMsg1)) { //80byte넘는 경우
			if (!CommonUtil.isLongerThan80Byte(gameName + url)) {
				smsMsg = tmpSmsMsg2;
			} else {
				smsMsg = url;
			}
		} else {
			smsMsg = tmpSmsMsg1;
		}

		return smsMsg;
	}

	/**
	 * 한게임 모바일 URL 문자보내기 문구 가져오기.
	 * 
	 * @return the sms msg for hg mobile
	 */
	private String getSmsMsgForHGMobile() {
		return WebContext.getMessage("sms.msg.for.hg") + " " + URL_HG_MOBILE;
	}
	
	/**
	 * 모바일 웹 접속.
	 * 
	 * @return the sms msg for smart mobile
	 * @return
	 */
	private String getSmsMsgForSmartMobile() {
		return WebContext.getMessage("sms.msg.for.hg") + " " + URL_SMART_MOBILE;
	}

}
